package com.gzu.shop.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzu.shop.common.Result;
import com.gzu.shop.common.ResultStatus;
import com.gzu.shop.constant.JwtClaimsConstant;
import com.gzu.shop.constant.MessageConstant;
import com.gzu.shop.constant.RoleConst;
import com.gzu.shop.constant.StatusConstant;
import com.gzu.shop.context.BaseContext;
import com.gzu.shop.entity.User;
import com.gzu.shop.exception.AccountExistedException;
import com.gzu.shop.exception.AccountNotFoundException;
import com.gzu.shop.exception.LoginFailedException;
import com.gzu.shop.exception.PasswordErrorException;
import com.gzu.shop.mapper.UserMapper;
import com.gzu.shop.properties.JwtProperties;
import com.gzu.shop.util.JwtUtil;
import com.gzu.shop.util.PasswordBcryptUtil;
import com.gzu.shop.vo.LoginVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

/**
 * @author Clown
 */
@Tag(name = "普通用户相关接口")
@RestController
@AllArgsConstructor
//@RequestMapping("/user")
public class LoginController {
    private JwtProperties jwtProperties;
    private UserMapper userMapper;

    @Operation(summary = "普通用户登录")
    @PostMapping("/user/login")
    public Result<LoginVO> userLogin(@RequestBody User user) {

        // 查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        user = userMapper.selectOne(queryWrapper.eq("username", user.getUsername()));
        // 查询数据为空，抛出异常
        if (ObjectUtil.isEmpty(user)) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }


        // 从数据库查询密码
        String hashedPassword = user.getPassword();
        // 密码为空，用户不存在
        if (hashedPassword.isEmpty()) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 密码不匹配
        if (PasswordBcryptUtil.checkPassword(user.getPassword(), hashedPassword)) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        // 封装前端对象
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(getToken(user));
        loginVO.setUsername(user.getUsername());
        loginVO.setRole(user.getRole());

        return Result.success(ResultStatus.SUCCESS, loginVO);
    }

    @Operation(summary = "用户注册")
    @PostMapping("/user/register")
    public Result<Void> userRegister(@RequestBody User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 查询用户是否已经存在
        boolean exists = userMapper.exists(queryWrapper.eq("username", user.getUsername()));
        // 用户存在，则抛出异常
        if (exists) {
            throw new AccountExistedException(MessageConstant.ACCOUNT_EXISTS);
        }
        // 得到原始密码
        String plainPassword = user.getPassword();
        // 得到加密后密码
        String hashedPassword = PasswordBcryptUtil.encryptPassword(plainPassword);
        // 将加密后密码存入
        user.setPassword(hashedPassword);
        // 设置角色
        user.setRole(RoleConst.USER);
        // 设置状态
        user.setStatus(StatusConstant.OPEN);
        // 插入数据
        userMapper.insert(user);

        return Result.success(ResultStatus.SUCCESS);
    }


    @Operation(description = "得到用户Token,并将userID,role存入token中")
    private String getToken(User user) {
        HashMap<String, Object> claims = new HashMap<>();
        // 将userID,role存入Map中
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        claims.put(JwtClaimsConstant.ROLE, user.getRole());
        // 得到token
        return JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);
    }

    @Operation(summary = "根据用户Id查询用户")
    @GetMapping("/user/getById")
    public Result<User> getById() {
        Integer o = (Integer) BaseContext.getThreadLocal().get(JwtClaimsConstant.USER_ID);
        return Result.success(ResultStatus.SUCCESS, userMapper.selectById(o));
    }


    @Operation(summary = "管理员登录")
    @PostMapping("/admin/login")
    public Result<LoginVO> adminLogin(@RequestBody User user) {

        // 查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        user = userMapper.selectOne(queryWrapper.eq("username", user.getUsername()));
        // 查询数据为空，抛出异常
        if (ObjectUtil.isEmpty(user)) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        if (!RoleConst.ADMIN.equals(user.getRole())) {
            throw new LoginFailedException(MessageConstant.ROLE_ERROR);
        }

        // 从数据库查询密码
        String hashedPassword = user.getPassword();
        // 密码为空，用户不存在
        if (hashedPassword.isEmpty()) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 密码不匹配
        if (PasswordBcryptUtil.checkPassword(user.getPassword(), hashedPassword)) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        // 封装前端对象
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(getToken(user));
        loginVO.setUsername(user.getUsername());
        loginVO.setRole(user.getRole());

        return Result.success(ResultStatus.SUCCESS, loginVO);
    }
}
